package io.mft.as.ar.gateway.client;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import io.mft.as.ar.gateway.constants.GatewayConstants;
import io.mft.as.ar.gateway.pool.BusPool;
import io.mft.as.ar.gateway.util.HttpUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 描述: 网关服务监听类
 * 		 liwei 20131209修改 增加长连接
 * 版权: Copyright (c) 2013 
 * 公司: 思迪科技 
 * 作者: 李建 
 * 版本: 1.0 
 * 创建日期: 2013-1-21 
 * 创建时间: 下午4:32:48
 */
public class GateWayListener extends Thread
{
    
    static
    {
        Map<String, Server> services = GateWayManager.getServers();
        if ( services != null )
        {
            Iterator<Map.Entry<String, Server>> iter = services.entrySet().iterator();
            while (iter.hasNext())
            {
                Map.Entry<String, Server> entry = (Map.Entry<String, Server>) iter.next();
                
                String gatewayName = entry.getKey();
                Server server = entry.getValue();
                if ( server != null )
                {
                    //20140416扫描间隔时间大于0，才启动后台扫描线程检查服务器是否存活
                    int scanInterval = server.getScanInterval();
                    if ( scanInterval > 0 )
                    {
                        if ( GatewayConstants.SCAN_SERVERTYPE_SOCKET.equals(server.getScanServerType())
                                && server.getMode() == GatewayConstants.INVOKE_MODE_LONG )
                        {
                            //启动长连接监控线程
                            NetAddress[] netAddressArr = server.getNetAddressArr();
                            List<BusPool> asPoolArr = null;
                            if ( netAddressArr != null )
                            {
                                asPoolArr = new ArrayList<BusPool>();
                                for (int i = 0; i < netAddressArr.length; i++)
                                {
                                    NetAddress nt = netAddressArr[i];
                                    BusPool asPool = new BusPool(server, gatewayName, nt.getIP(), nt.getPort(),
                                            server.getPoolSize(), server.getRecvTimeout(), server.getKey(),
                                            server.getVersion());
                                    asPool.start();
                                    asPool.startCheckPoolExpire();
                                    asPoolArr.add(asPool);
                                }
                            }
                            server.setAsPoolArr(asPoolArr);
                            
                        }
                        //启动短连接监控线程
                        ASCheckThread busThread = new ASCheckThread(gatewayName);
                        new Thread(busThread, "BusCheckThread-" + gatewayName).start();
                        
                    }
                }
                
            }
        }
    }
    
    public GateWayListener()
    {
        
    }
    
    @Override
    public void run()
    {
        
    }
}

/**
 *
 * 描述: 检测AS是否存活
 * 版权: Copyright (c) 2012
 * 公司: 思迪科技 
 * 作者: 李炜
 * 版本: 1.0 
 * 创建日期: Dec 4, 2013 
 * 创建时间: 11:34:25 AM
 */
@Slf4j
class ASCheckThread extends Thread
{
    
    
    private String        key    = "";
    
    public ASCheckThread(String key)
    {
        this.key = key;
    }
    
    @Override
    public void run()
    {
        String gateWayName = "";
        int scanInterval = 0;
        NetAddress[] netAddressArr;
        Server server;
        NetAddress nt;
        String ipStr;
        List<BusPool> busPoolAll;
        BusPool asPool;
        
        while (true)
        {
            try
            {
                server = GateWayManager.getServerByBusConfigId(key);
                if ( server != null )
                {
                    gateWayName = server.getGateWayName();
                    scanInterval = server.getScanInterval();
                    netAddressArr = server.getNetAddressArr();
                    
                    if ( netAddressArr != null && netAddressArr.length > 0 )
                    {
                        for (int i = 0; i < netAddressArr.length; i++)
                        {
                            nt = (NetAddress) netAddressArr[i];
                            if ( nt == null )
                            {
                                continue;
                            }
                            ipStr = nt.getIP();
                            int port = nt.getPort();
                            if ( GatewayConstants.SCAN_SERVERTYPE_SOCKET.equals(server.getScanServerType())
                                    && server.getMode() == GatewayConstants.INVOKE_MODE_LONG )
                            {
                                //长连接处理模式，当增加或减少服务器信息时，需要初始化连接池
                                busPoolAll = server.getAsPoolArr();
                                boolean isExists = false;
                                for (BusPool busPool : busPoolAll)
                                {
                                    //判断当前的IP地址是否已经创建了连接池
                                    if ( ipStr.equals(busPool.getHost()) && port == busPool.getPort() )
                                    {
                                        isExists = true;
                                        break;
                                    }
                                }
                                //如果当前的IP地址未创建连接池，需要创建连接池
                                if ( !isExists )
                                {
                                    asPool = new BusPool(server, key, nt.getIP(), nt.getPort(), server.getPoolSize(),
                                            server.getRecvTimeout(), server.getKey(), server.getVersion());
                                    asPool.start();
                                    
                                    server.setAsPoolArr(asPool);
                                }
                                
                            }
                            else
                            {
                                //短连接处理模式，连接判断服务器是否存活，在内存中标识存活状态
                                boolean isAlive = HttpUtil.connectServer(nt);
                                nt.setAlive(isAlive);
                                if ( !isAlive )
                                {
                                    log.error("网关服务器" + gateWayName + "[" + ipStr + ":" + port + "]是否存活=" + isAlive);
                                }
                                else
                                {
                                    log.debug("网关服务器" + gateWayName + "[" + ipStr + ":" + port + "]是否存活=" + isAlive);
                                }
                            }
                        }
                    }
                    else
                    {
                        log.warn("网关[" + gateWayName + "]配置的IP地址为空，请检查!");
                    }
                }
                else
                {
                    log.warn("网关服务器" + gateWayName + "不存在");
                }
                
            }
            catch (Exception ex)
            {
                log.error("", ex);
            }
            //线程暂停
            if ( scanInterval <= 0 )
            {
                scanInterval = 5 * 1000;
            }
            try
            {
                sleep(scanInterval);
            }
            catch (InterruptedException e)
            {
                log.error("", e);
            }
        }
    }
}
